package com.example.onlinemonitoring.Util;

import com.example.onlinemonitoring.Util.tem.SensorAbstractBaseService;
import com.example.onlinemonitoring.WebSocket.TestWebSocketHandler;
import com.example.onlinemonitoring.autoRun.ComRunner;
import com.example.onlinemonitoring.autoRun.ComTcp;
import com.example.onlinemonitoring.model.Appalarm;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.common.NetWork;
import com.example.onlinemonitoring.model.common.alarmmessage;
import com.example.onlinemonitoring.model.common.sensor;
import com.example.onlinemonitoring.model.common.series;
import com.example.onlinemonitoring.serviceImpl.AppalarmServiceImpl;
import com.example.onlinemonitoring.serviceImpl.AppdeviceServiceImpl;
import com.example.onlinemonitoring.serviceImpl.AppstationServiceImpl;
import com.example.onlinemonitoring.model.Appstation;
import ch.qos.logback.core.net.server.Client;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import com.example.onlinemonitoring.Iec104.config.Iec104Config;
import com.example.onlinemonitoring.Iec104.server.Iec104MasterFactory;
import com.example.onlinemonitoring.Iec104.task.MasterSysDataHandler;
import com.example.onlinemonitoring.Util.LanguageManager;
import org.slf4j.LoggerFactory;
import org.mybatis.spring.MyBatisSystemException;
import org.slf4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.annotation.Async;
import com.example.onlinemonitoring.model.common.MBAPheader;

import io.netty.handler.codec.stomp.StompCommand;
import lombok.Data;
import tk.mybatis.mapper.entity.Example;
import java.io.*;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

@Data
public class CommPortManager extends HexUtil {
    @Autowired
    LanguageManager languageManager;
    @Autowired
    AppalarmServiceImpl Appalarmserviceimpl;
    @Autowired
    AppstationServiceImpl appstationserviceimpl;
    @Autowired
    BeanFactory beanFactory;
    @Autowired
    AppdeviceServiceImpl appdeviceserviceimpl;
    protected static Logger logger = LoggerFactory.getLogger(CommPortManager.class);
    protected Appdevice ad;// 设备信息
    protected static final boolean OFF = false;
    protected static final boolean ON = true;
    protected String tmp = "";// 临时字符串
    protected String buffer = "";// 缓冲区
    protected StringBuffer sbuffer = new StringBuffer();// socket短连接缓冲区
    protected int slen = 0;// socket短连接缓冲区长度
    String path = "";
    protected volatile HashMap<Long, Boolean> issend = new HashMap<Long, Boolean>();
    protected HashMap<Long, Boolean> isrecv = new HashMap<Long, Boolean>();
    protected int reSend[] = new int[255];
    protected Integer interval = 50;
    protected Integer timersp = 0;
    protected Integer timeoutsp = 0;
    protected String DischargeType[] = { "颗粒放电", "电极放电", "间隙放电", "电晕放电", "未知局放类型" };
    protected String DischargeType_eby[] = { "Descarga de partículas", "Descarga de electrodos", "Descarga de brecha",
            "Descarga de corona", "Tipo de juego desconocido" };
    protected String DischargeTypeXY[] = { "正常", "尖端放电", "悬浮放电", "沿面放电", "内部放电", "颗粒放电", "外部干扰", "未知局放类型" };
    protected Integer addrindex = -1;
    protected DecimalFormat df = new DecimalFormat("00");
    public NetWork network;
    public Socket socket;
    public InputStream is;
    public OutputStream os;
    public BufferedReader br;
    public String STATION_PATH = "";
    public String PREFIX_PATH = "";
    volatile public boolean isrun = false;// 串口打开后，第一时间并没有真正开启，需要接收串口工具返回值判断是否开启，然后再运行
    public Integer rescode = 0;// 串口打开失败的状态值
    protected String resmsg[] = { "串口已开启", "串口被占用", "未知错误" };// 串口打开失败的原因
    public String checkType = "";
    protected boolean useseries = true;
    protected String controllerCmd = "";// 遥控命令
    protected String controllerRet = "";// 遥控返回命令
    boolean ProhibitSending = false;// 关闭串口的时候禁止发送
    public Integer socketConnectType = 0;// 0长连接1短连接
    public Integer timeout = 300;// ms 数据在qt串口缓冲区中不再接收数据的时间
    public boolean availableRet = false;// 判断缓冲区是否可用（无数据）的返回命令
    public Integer seriesNum = -1;
    protected int currcmd = 0;// 当前请求报文的序号
    public static int dlhlVertype = 0;
    // Appstation aps = null;
    public static Integer Language = 0;
    public Timer timerPd = new Timer();
    public boolean timerFlag = true;
    /* 以下是服务端的配置 */
    public ServerSocket server;
    public Socket sclsocket;
    public Map<AtomicInteger, InputStream> ismap = new HashMap<>();
    public Map<AtomicInteger, OutputStream> osmap = new HashMap<>();
    public Map<AtomicInteger, Socket> smap = new HashMap<>();
    public Map<AtomicInteger, Boolean> isnetrun = new HashMap<>();
    public AtomicInteger scount = new AtomicInteger(0);

    public static Map<AtomicInteger, OutputStream> ossmap = new HashMap<>();
    public static Map<AtomicInteger, Socket> ssmap = new HashMap<>();
    public static ArrayList<Socket> ssList = new ArrayList<>();

    // 串口收发时使用可重入锁
    protected ReentrantLock rlock = new ReentrantLock(true);
    protected Condition sendCondition = rlock.newCondition();// 发送线程锁条件
    protected Condition recvCondition = rlock.newCondition();// 接收线程锁条件
    protected Condition controlCondition = rlock.newCondition();// 遥控线程锁条件
    protected boolean sendFlag = true;// 有报文主动上发时，设置为false
    public long starttime = 0;
    public long lastnetrecvtime = 0;
    int localport = 0;// tcp转发时，本地端口累加，防止端口阻塞
    protected boolean allowDisplay = true;// 是否允许展示发送的报文（如果想用自定义发送报文格式要把这个关了）
    protected boolean prohibitSending = false;// 发送遥控命令的时候禁止放开遥测或者遥信发送同步锁
    OutputStream serverout = null;// 服务端输出
    public Map<String, String> map61850 = new HashMap<>();
    private static final int CLIENT61850PORT = 8298;
    // private static final int CLIENT61850PORT = 102;
    @Value("${Config61850.CLIENT61850IP}")
    String CLIENT61850IP = "127.0.0.1";
    // private static final String CLIENT61850IP = "127.0.0.1";
    // private static final String CLIENT61850IP = "192.168.17.133";
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Lock readLock = readWriteLock.readLock();
    private final Lock writeLock = readWriteLock.writeLock();

    public String modifySuccess = "修改成功";
    public MBAPheader header = new MBAPheader();

    /**
     * 第一阶段：初始化
     * 
     * @throws Exception
     */
    public boolean Initialize(Appdevice ad) {
        try {
            if (ad != null) {
                this.ad = ad;
                localport = isnull(ad.getLocalport());
                starttime = new Date().getTime();
                lastnetrecvtime = new Date().getTime();
                timersp = (int) Math.round(ad.getTimersp() * 1000);
                timeoutsp = (int) Math.round(ad.getTimeoutsp() * 1000);
                myInit();// 自定义初始化要做的事情

                switch (ad.getCommunicationmode()) {
                    case 1:
                        return setCom();// 1串口
                    case 2:
                        return setNet();// 2网口客户端
                    case 3:
                        return setNetServer();// 3网口服务端
                    case 4:
                        return set61850Client();// 4 61850客户端
                    case 5:
                        return setUSBCom();// usb
                    case 6:
                        return setNet();// 6modbustcp网口客户端
                    default:
                        break;
                }
            }
            return false;
        } catch (Exception ex) {
            System.out.println("Initialize:" + ex);
            return false;
        }
    }

    protected void myInit() {
        Language = getLanguage();
        header.TransactionID = 1;
        header.ProtocolID = 0;
        header.Length = 6;
        header.UnitID = 1;
    }

    protected int getLanguage() {
        Appstation as = new Appstation();
        as.setId(1);
        as = appstationserviceimpl.selectByPrimaryKey(as);
        Language = as.getLanguage();

        return Language;
    }

    /**
     * 第二阶段：开启设备
     * 
     * @throws Exception
     */
    public boolean Open() throws Exception {
        switch (ad.getCommunicationmode()) {
            case 1:
                return openCom();// 1串口
            default:
                break;
        }
        return false;
    }

    /**
     * 第三阶段：发送数据
     * 
     * @throws Exception
     */
    public void Sendtcp(String msg, Socket sk) {

        if (sk != null) {
            try {
                OutputStream os = sk.getOutputStream();
                serverout = os;
                serverout.write(HexUtil.hexString2Bytes(msg));
            } catch (Exception e) {
                setText(e.toString());
                try {
                    sk.close();
                } catch (IOException e1) {
                    // 关闭Socket时的异常处理
                }
            }
        }
    }

    /**
     * 第三阶段：发送数据
     * 
     * @throws Exception
     */
    public void Send(String msg) {

        if (serverout != null) {
            try {
                serverout.write(HexUtil.hexString2Bytes(msg));
            } catch (Exception e) {
                setText(e.toString());
            }
        } else {

            try {
                if (ad.getCommunicationmode() == 6) {
                    header.TransactionID++;
                    if (header.TransactionID > 65535)
                        header.TransactionID = 1;
                    int Length = msg.length() / 2;
                    header.ProtocolID = 0;
                    String sheader = String.format("%04x", header.TransactionID)
                            + String.format("%04x", header.ProtocolID) + String.format("%04x", (short) Length);
                    msg = sheader + msg;
                }
                if (ProhibitSending) {
                    return;
                }
                switch (ad.getCommunicationmode()) {
                    case 1:
                        sendCom(msg);
                        break;// 1串口
                    case 2:
                    case 6:
                        if (socketConnectType == 0) {
                            sendLongNet(msg);
                        } else {
                            sendNet(msg);
                        }
                        break;// 2网口
                    default:
                        break;
                }
                setText(ad.getName() + "  TX:" + msg);
            } catch (Exception e) {
                setText(e.toString());
            }
        }
    }

    /**
     * 第三阶段：发送数据，重载Send函数，在Send之前判断out是否为空
     * 
     * @throws Exception
     */
    public void Send(String msg, OutputStream out) {
        if (out == null) {
            Send(msg);
            return;
        }
        try {
            out.write(HexUtil.hexString2Bytes(msg));
        } catch (Exception e) {
            setText(e.toString());
        }
    }

    /**
     * 第四阶段：遵从crc16校验、累加校验和等接收数据
     * 累加和校验目前只支持网口
     * 
     * @throws Exception
     */
    public void recvSum(String str) {
        try {
            if (is == null) {
                return;
            }
            String s = "";
            int available = is.available();
            if (available != 0) {
                System.out.println(available);
                byte[] bt = new byte[available];
                is.read(bt);
                sbuffer.append(HexUtil.bytes2HexString(bt).replaceAll("\\s", ""));
                slen += available;
                // receiveData(s, null);
            }
        } catch (SocketException e) {

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 第四阶段：直接接收
     * 
     * @throws Exception
     */
    @Async("threadPoolm")
    public void recv(String str) {
        switch (checkType) {
            case "crc16":
                recvCrc16Com(str);
                break;
            case "sum":
                recvSum(str);
                break;
            default:
                receiveData(str, null);
                break;
        }
    }

    /**
     * 第五阶段：关闭设备
     * 
     * @throws Exception
     */
    public boolean Close() {
        myClose();
        switch (ad.getCommunicationmode()) {
            case 1:
                try {
                    return closeCom();// 1串口
                } catch (Exception e) {
                    e.printStackTrace();
                }
            case 2:
            case 6:
                return closeNet();// 2网口
            case 3:
                return closeNetServer();// 3网口
            case 4:
                return closeNetServer();// 4 61850网口
            case 5:
                return closeUSB();
            default:
                break;
        }
        return false;
    }

    public void myClose() {

    }

    /**
     * 设置串口参数
     * 
     * @throws Exception
     */
    public boolean setCom() {
        seriesNum = strGetNum(ad.getCom());
        return openCom();
    }

    /**
     * 设置串口参数
     * 
     * @throws Exception
     */
    public boolean setUSBCom() {
        // seriesNum = strGetNum(ad.getCom());
        return true;
    }

    /**
     * 设置网口参数
     * 
     * @throws IOException
     * @throws UnknownHostException
     * 
     * @throws Exception
     */
    public boolean setNet() {
        boolean res = true;
        try {
            setText(ad.getName() + "服务器连接中...");
            InetSocketAddress address = new InetSocketAddress(ad.getIp(), ad.getPort());
            InetSocketAddress localAddr = new InetSocketAddress(ad.getLocalip(), localport);
            socket = new Socket();
            // socket.setReuseAddress(true);
            // socket.setSoTimeout(1000);
            socket.bind(localAddr);
            socket.connect(address);
            is = socket.getInputStream();
            os = socket.getOutputStream();
            setText("连接成功！");
            lastnetrecvtime = new Date().getTime();
            isrun = true;
            localport++;
            if (localport > 60000) {
                localport = ad.getPort();
            }
        } catch (ConnectException ex) {
            setText("远程主机" + ad.getIp() + "连接失败！连接超时无响应！");
            return res = false;
        } catch (UnknownHostException ex) {
            setText("远程主机" + ad.getIp() + "连接失败！不知道这样的主机！");
            return res = false;
        } catch (BindException ex) {
            setText(ex.toString());
            setText("远程主机" + ad.getIp() + "连接失败！本地端口" + localport + "还未释放或被占用！");
            localport++;
            if (localport > 60000) {
                localport = ad.getPort();
            }
            return res = false;
        } catch (Exception ex) {
            setText(ex.toString());
            setText("远程主机" + ad.getIp() + "连接失败！未知错误！");
            return res = false;
        } finally {
            if (!res) {
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return res;
    }

    public boolean setNetServer() {
        isrun = true;
        boolean res = true;
        new Thread(() -> {
            try {
                setText("服务器启动...............");
                server = new ServerSocket(ad.getLocalport());
                while (true) {
                    // 阻塞，直到有客户连接
                    Socket sk = server.accept();

                    // 启动服务线程
                    new ServerThread(sk).start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        return res;
    }

    // 使用线程为多个客户端服务
    class ServerThread extends Thread {
        private Socket sk;

        ServerThread(Socket sk) {
            this.sk = sk;
            scount.incrementAndGet();

        }

        // 线程运行实体
        public void run() {

            isnetrun.put(scount, true);
            smap.put(scount, sk);
            ssList.add(sk);
            try {
                InputStream is = sk.getInputStream();
                OutputStream os = sk.getOutputStream();
                ismap.put(scount, is);
                osmap.put(scount, os);
                ossmap.put(scount, os);
                // 接收来自客户端的请求，根据不同的命令返回不同的信息
                String s = "";
                byte[] bt = new byte[1];
                int bytesRead = 0;
                //while (isnetrun.get(scount)) {
                while ( (bytesRead = is.read(bt)) != -1) {
                    InetSocketAddress socketAddress = (InetSocketAddress) sk.getRemoteSocketAddress();
                    String clientIpAddress = socketAddress.getAddress().getHostAddress();
                    ad.setIp(clientIpAddress);


                    writeLock.lock();
                    //is.read(bt);
                    sclsocket = sk;
                    int available = is.available();
                    if (available != 0) {
                        byte[] bt1 = new byte[available];
                        is.read(bt1);
                        byte[] bt2 = byteConcat(bt, bt1);
                        s = HexUtil.bytes2HexString(bt2).replaceAll("\\s", "");

                        receiveData(s, os);

                    }
                    writeLock.unlock();
                    Thread.sleep(30);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (is != null) {
                        is.close();
                    }
                    if (os != null) {
                        os.close();
                    }
                    if (sk != null) {
                        sk.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }

    }

    public void setDisconnected() {

    }

    public boolean set61850Client() {

        boolean res = true;
        try {
            setText(ad.getName() + "代理服务器连接中...");

            InetSocketAddress address = new InetSocketAddress(CLIENT61850IP, CLIENT61850PORT);
            socket = new Socket();
            socket.connect(address);
            is = socket.getInputStream();
            os = socket.getOutputStream();
            setText("代理服务器连接成功！");
            String sendtext = "1|" + ad.getIp() + "|102";
            os.write(sendtext.getBytes());
            Long timestamp = System.currentTimeMillis() + 1000 * 15;
            while (System.currentTimeMillis() < timestamp) {
                int available = is.available();
                if (available != 0) {
                    byte[] bt = new byte[available];
                    is.read(bt);
                    String s = new String(bt);
                    if (s.equals("1|1")) {
                        setText("61850客户端连接成功！");
                        return true;
                    } else {
                        setText("61850客户端连接失败，客户端不在线或者IP和端口设置错误！");
                        return false;
                    }
                }
            }
            res = false;
        } catch (ConnectException ex) {
            setText("代理服务器连接失败！连接超时无响应！");
            return res = false;
        } catch (UnknownHostException ex) {
            setText("代理服务器连接失败！不知道这样的主机！");
            return res = false;
        } catch (BindException ex) {
            setText(ex.toString());
            setText("代理服务器连接失败！本地端口" + localport + "还未释放或被占用！");
            return res = false;
        } catch (Exception ex) {
            setText(ex.toString());
            setText("代理服务器连接失败！未知错误！");
            return res = false;
        }
        return res;
    }

    public int isread61850Value(String path) throws SocketException, IOException {
        if (path == null || path.equals("")) {
            return 0;
        }
        String sendtext = "2|" + path + "|1";
        os.write(sendtext.getBytes());
        Long timestamp = System.currentTimeMillis() + 1000 * 1;
        while (System.currentTimeMillis() < timestamp) {
            int available = is.available();
            if (available != 0) {
                byte[] bt = new byte[available];
                is.read(bt);
                String s = new String(bt);
                if (s.substring(0, 2).equals("2|")) {
                    if (!s.equals("2|Failed") && !s.equals("2|") && !s.contains("Failed")
                            && !s.equals("2|DisConnected")) {
                        return 0;
                    } else if (s.equals("2|DisConnected")) {
                        setText("请求" + sendtext + "的时候61850断开连接");
                        if (Close()) {
                            ComRunner.netmap.remove(ad.getId());
                        }
                    } else {
                        setText("61850读取路径错误 错误的路径：" + path);
                        return 1;
                    }
                } else {
                    return 1;
                }
            }
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return 1;
    }

    public float read61850FloatValue(String path) throws SocketException, IOException {
        if (path == null || path.equals("")) {
            return 0f;
        }
        String sendtext = "2|" + path + "|1";
        os.write(sendtext.getBytes());
        Long timestamp = System.currentTimeMillis() + 1000 * 1;
        while (System.currentTimeMillis() < timestamp) {
            int available = is.available();
            if (available != 0) {
                byte[] bt = new byte[available];
                is.read(bt);
                String s = new String(bt);
                if (s.substring(0, 2).equals("2|")) {
                    if (!s.equals("2|Failed") && !s.equals("2|") && !s.contains("Failed")
                            && !s.equals("2|DisConnected")) {
                        return Double.valueOf(s.substring(2, s.length())).floatValue();
                    } else if (s.equals("2|DisConnected")) {
                        setText("请求" + sendtext + "的时候61850断开连接");
                        if (Close()) {
                            ComRunner.netmap.remove(ad.getId());
                        }
                    } else {
                        setText("61850读取路径错误 错误的路径：" + path);
                        return 0f;
                    }
                } else {
                    return 0f;
                }
            }
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return 0f;
    }

    public int read61850IntValue(String path) throws SocketException, IOException {
        if (path == null || path.equals("")) {
            return 0;
        }
        String sendtext = "2|" + path + "|0";
        os.write(sendtext.getBytes());
        Long timestamp = System.currentTimeMillis() + 1000 * 1;
        while (System.currentTimeMillis() < timestamp) {
            int available = is.available();
            if (available != 0) {
                byte[] bt = new byte[available];
                is.read(bt);
                String s = new String(bt);
                if (s.substring(0, 2).equals("2|")) {
                    if (!s.equals("2|Failed") && !s.equals("2|") && !s.contains("Failed")) {
                        return Integer.parseInt(s.substring(2, s.length()));
                    } else if (s.equals("2|DisConnected")) {
                        setText("请求" + sendtext + "的时候61850断开连接");
                        if (Close()) {
                            ComRunner.netmap.remove(ad.getId());
                        }
                    } else {
                        setText("61850读取路径错误 错误的路径：" + path);
                        return 0;
                    }

                } else {
                    return 0;
                }
            }
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return 0;
    }

    public String read61850Dec(String path) throws SocketException, IOException {
        if (path == null || path.equals("")) {
            return "";
        }
        String sendtext = "2|" + path + "|5";
        os.write(sendtext.getBytes());
        Long timestamp = System.currentTimeMillis() + 1000 * 1;
        while (System.currentTimeMillis() < timestamp) {
            int available = is.available();
            if (available != 0) {
                byte[] bt = new byte[available];
                is.read(bt);
                String s = new String(bt);
                if (s.substring(0, 2).equals("2|")) {
                    if (!s.equals("2|Failed") && !s.equals("2|") && !s.contains("Failed")) {
                        return s.substring(2, s.length());
                    } else if (s.equals("2|DisConnected")) {
                        setText("请求" + sendtext + "的时候61850断开连接");
                        if (Close()) {
                            ComRunner.netmap.remove(ad.getId());
                        }
                    } else {
                        setText("61850读取路径错误 错误的路径：" + path);
                        return "";
                    }

                } else {
                    return "";
                }
            }
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 判断串口缓冲区是否可用
     *
     * @throws Exception
     */
    public boolean isAvailable() {
        if (ad.getCommunicationmode() == 1) {
            availableRet = false;
            String cmd = "ISAVA";
            ComRunner.ct[seriesNum].send(cmd);
            // 设置超时时间3s
            Long timestamp = System.currentTimeMillis() + 1000 * 3;
            while (System.currentTimeMillis() < timestamp) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (availableRet) {
                    return availableRet;
                }
            }
            return availableRet;
        } else {
            return true;
        }
    }

    /**
     * 打开串口
     * 
     * @throws Exception
     */
    public boolean openCom() {
        ProhibitSending = false;
        setText("正在打开" + ad.getName());
        float Baudrate = ad.getBaudrate();
        String cmd = "OPEN," + (int) Baudrate + "," + timeout;
        // if(ad.getCom().contains("USB"))
        // {
        // CommPortManager cp = (CommPortManager) context.getBean(appdevice.getSimple()
        // + "Com");
        // netmap.put(appdevice.getId(), cp);
        // cp.startSendThread(appdevice);
        // return true;
        // }

        return ComRunner.ct[seriesNum].send(cmd);
    }

    public boolean closeUSB() {
        issend.clear();
        isrecv.clear();
        setTimerFlag(false);
        return true;
    }

    /**
     * 关闭串口
     * 
     * @throws Exception
     */
    public boolean closeCom() throws Exception {
        issend.clear();
        isrecv.clear();
        /*
         * String cmd = "CLOSE,"+ ad.getCom();
         * comTcp.send(cmd);
         * setText("关闭串口" + ad.getCom());
         */
        return true;
    }

    /**
     * 关闭串口
     *
     * @throws Exception
     */
    public boolean closeComByTcp() {
        ProhibitSending = true;
        String cmd = "CLOSE";
        ComRunner.ct[seriesNum].send(cmd);
        setText("关闭串口" + ad.getCom());
        return true;
    }

    /**
     * 关闭网口
     * 
     * @throws Exception
     */
    public boolean closeNet() {
        issend.clear();
        isrecv.clear();
        setTimerFlag(false);
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
            }
        }
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
            }
        }
        setText("关闭网口" + ad.getIp());
        return true;
    }

    /**
     * 关闭网口
     * 
     * @throws Exception
     */
    public boolean closeNetServer() {
        serverout = null;
        issend.clear();
        isrecv.clear();
        try {
            for (int i = 0; i < ssList.size(); i++)
                ssList.get(i).close();

            for (AtomicInteger key : ismap.keySet()) {
                ismap.get(key).close();
            }
            for (AtomicInteger key : osmap.keySet()) {
                osmap.get(key).close();
            }
            for (AtomicInteger key : smap.keySet()) {
                smap.get(key).close();
            }
            if (server != null) {
                server.close();
            }
        } catch (IOException e) {
        }
        for (AtomicInteger key : isnetrun.keySet()) {
            isnetrun.put(key, false);
        }
        setText("关闭服务端");
        return true;
    }

    /**
     * 关闭61850网口
     * 
     * @throws Exception
     */
    public boolean close61850NetServer() {
        try {
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
            if (server != null) {
                server.close();
            }
            setText("关闭61850服务端");
            return true;
        } catch (IOException e) {
        }
        return false;
    }

    /**
     * 按照crc16协议接收数据（串口）
     * 
     * @throws Exception
     */
    public void recvCrc16Com(String str) {
        try {
            // if (str.length() > 5
            // && CRC16.calcCrc16(str.substring(0, str.length() -
            // 4)).equals(str.substring(str.length() - 4))) {
            receiveData(str, null);
            // }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 按照crc16协议接收数据（网口）
     * 
     * @throws Exception
     */
    public void recvCrc16Net() {
        String s = "";
        try {
            if ((new Date().getTime() - lastnetrecvtime) > 300000) {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                    }
                }
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                    }
                }
                setNet();
            }
            int available = is.available();
            if (available != 0) {
                byte[] bt = new byte[available];
                is.read(bt);

                lastnetrecvtime = new Date().getTime();
                s = HexUtil.bytes2HexString(bt).replaceAll("\\s", "");
                setText(s);
                if (ad.getCommunicationmode() == 6) {
                    String cstr = s.substring(12, s.length());
                    receiveData(cstr, null);
                } else
                    // if (s.length() > 5
                    // && CRC16.calcCrc16(s.substring(0, s.length() -
                    // 4)).equals(s.substring(s.length() - 4))) {
                    receiveData(s, null);
                // }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @方法名称 :sendCom
     * @功能描述 :向端口发送数据(串口)
     * @返回值类型 :void
     * @param message
     */
    public void sendCom(String msg) {
        String cmd = "SEND," + msg;
        ComRunner.ct[seriesNum].send(cmd);
    }

    /**
     * @方法名称 :sendNet
     * @功能描述 :向端口发送数据（网口、短连接）
     * @返回值类型 :void
     * @param message
     */
    public void sendNet(String msg) {
        allowDisplay = false;
        try {
            if (socket != null) {
                socket.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        if (setNet()) {
            try {
                setText("向" + ad.getName() + "监控设备发送" + msg);
                os.write(HexUtil.hexString2Bytes(msg));
                Thread.sleep(500);
                socket.shutdownOutput();
                socket.shutdownInput();
                receiveData(sbuffer.toString(), null);
                slen = 0;
                sbuffer = new StringBuffer();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * @方法名称 :sendNet
     * @功能描述 :向端口发送数据（网口、长连接）
     * @返回值类型 :void
     * @param message
     */
    public void sendLongNet(String msg) {
        try {
            os.write(HexUtil.hexString2Bytes(msg));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static List<String> getPortList() {
        List<String> list = new ArrayList<>();
        if (HexUtil.isWindows()) {
            list.add("COM1");
            list.add("COM2");
            list.add("COM3");
            list.add("COM4");
            list.add("COM5");
            list.add("COM6");
            list.add("COM7");
            list.add("COM8");
            list.add("COM9");
            list.add("COM10");
            return list;
        } else {
            list.add("/dev/ttyS0");
            list.add("/dev/ttyS1");
            list.add("/dev/ttyS2");
            list.add("/dev/ttyS3");
            list.add("/dev/ttyS4");
            list.add("/dev/ttyS5");
            list.add("/dev/ttyS6");
            list.add("/dev/ttyS7");
            list.add("/dev/ttyS8");
            list.add("/dev/ttyS9");
            return list;
        }
    }

    /**
     * 判断串口是否可用
     */
    public boolean commPortEnable() {
        boolean result = false;
        return result;
    }

    /**
     * 设置串口接收超时时间
     * 
     * @param timeout 超时时间，单位秒
     * @throws Exception
     */
    public void setReceiveTimeout(int timeout) throws Exception {
        // getSerialPort().enableReceiveTimeout(timeout * 1000);
    }

    public void receiveData(String str, OutputStream out) {
        if (out == null) {
            receiveData(str);
        } else {
            serverout = out;
            receiveData(str);
        }
    }

    /**
     * 输出文本内容。
     * 
     * @param str 要设置的文本字符串
     */
    public void setText(String str) {
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]:");
        String datestr = sdf.format(d);
        TestWebSocketHandler.sendAllMessage(datestr + str,
                ad.getSimple() + "s" + ad.getStationid() + "d" + ad.getDevicegroup());
        System.out.println(datestr + str);
        logger.info(datestr + str);
    }

    /**
     * 输出错误信息。
     * 
     * @param str 错误信息字符串
     */
    public void setError(String str) {
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]:");
        String datestr = sdf.format(d);
        TestWebSocketHandler.sendAllMessage(datestr + str,
                ad.getSimple() + "s" + ad.getStationid() + "d" + ad.getDevicegroup());
        System.out.println(datestr + str);
        logger.error(datestr + str);
    }

    /**
     * 
     * @param value          传递的值
     * @param alarmValue     报警值
     * @param warnValue      预警值
     * @param valueLevel     返回报警等级
     * @param alarmLevel     上次报警等级
     * @param contrastStatus 低报还是高报
     * @return
     */
    public static int GetAlarmStatus(float value, float alarmValue, float warnValue, int valueLevel, int alarmLevel,
            Boolean contrastStatus) {
        // 获取报警状态
        // 、引用的报警等级、对比状态默认按大于对比，如果是false按小于
        // 返回值：0正常 1预警 2报警
        if (contrastStatus) {
            if (value >= alarmValue) {
                valueLevel = 2; // 上次值报警等级
                alarmLevel = 2; // 引用的报警等级
            } else if (value >= warnValue) {
                valueLevel = 1;
                if (alarmLevel != 2)
                    alarmLevel = 1;
            } else
                valueLevel = 0;
        } else {
            if (value <= alarmValue) {
                valueLevel = 2; // 上次值报警等级
                alarmLevel = 2; // 引用的报警等级
            } else if (value <= warnValue) {
                valueLevel = 1;
                if (alarmLevel != 2)
                    alarmLevel = 1;
            } else
                valueLevel = 0;
        }

        return valueLevel;
    }

    /**
     * 
     * @param value             传递的值
     * @param alarmValue        报警值
     * @param alarmRelieveValue 报警解除值
     * @param warnValue         预警值
     * @param warnRelieveValue  预警解除值
     * @param valueLevel        上次值报警等级
     * @param contrastStatus    true高报false低报
     * @return
     */
    public static int GetAlarmStatus(float value, float alarmValue, float alarmRelieveValue, float warnValue,
            float warnRelieveValue, int valueLevel, Boolean contrastStatus) {
        int alarmLevel = 0;
        // 获取报警状态
        // 参数:分别是传递的值、报警值、报警解除值、预警值、预警解除值、上次值报警等级
        // 返回值：0正常 1预警 2报警
        if (contrastStatus) {
            if (value >= alarmValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 2;
                        break;
                    case 1:
                        alarmLevel = 2;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value >= alarmRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value >= warnValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else if (value >= warnRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 0;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else {
                alarmLevel = 0;
            }
        } else {
            if (value <= alarmValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 2;
                        break;
                    case 1:
                        alarmLevel = 2;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value <= alarmRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value <= warnValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else if (value <= warnRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 0;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else {
                alarmLevel = 0;
            }
        }
        return alarmLevel;
    }

    /**
     * 新版告警(带监测点)
     * 
     * @param value             传递的值
     * @param alarmValue        报警值
     * @param alarmRelieveValue 报警解除值
     * @param warnValue         预警值
     * @param warnRelieveValue  预警解除值
     * @param valueLevel        旧的报警等级
     * @param contrastStatus    true高报false低报
     * @return alarmLevel 新的报警等级
     */
    public int GetAlarmStatus(float value, float alarmValue, float alarmRelieveValue, float warnValue,
            float warnRelieveValue, int valueLevel, Boolean contrastStatus, String alarmcolumn,
            int devicegroup, int addr, String pointname, int pointaddr) {
        String alarmmessage = alarmcolumn;
        alarmcolumn += "sbz" + devicegroup + "dz" + addr + "jcd" + pointaddr + "qt";
        return GetAlarm(value, alarmValue, alarmRelieveValue, warnValue, warnRelieveValue, valueLevel, contrastStatus,
                alarmcolumn, alarmmessage, addr, pointname, pointaddr);
    }

    /**
     * 新版告警(不带监测点)
     * 
     * @param value             传递的值
     * @param alarmValue        报警值
     * @param alarmRelieveValue 报警解除值
     * @param warnValue         预警值
     * @param warnRelieveValue  预警解除值
     * @param valueLevel        旧的报警等级
     * @param contrastStatus    true高报false低报
     * @return alarmLevel 新的报警等级
     */
    public int GetAlarmStatus(float value, float alarmValue, float alarmRelieveValue, float warnValue,
            float warnRelieveValue, int valueLevel, Boolean contrastStatus, String alarmcolumn, int devicegroup,
            int addr, String pointname) {
        return GetAlarm(value, alarmValue, alarmRelieveValue, warnValue, warnRelieveValue, valueLevel, contrastStatus,
                alarmcolumn, alarmcolumn, addr, pointname, -1);
    }

    /**
     * 常规报警
     * 
     * @param alarmcolumn 唯一项，报警列，请勿重复
     * @param addr        地址
     * @param pointaddr   监测点地址
     * @param pointname   监测点名称
     * @param msg         需要展示的报警详情
     * @param isalarm     是否需要恢复，true表示需要报警，false表示需要恢复为正常
     */
    public void GetNormalAlarm(String alarmcolumn, int devicegroup, int addr, int pointaddr, String pointname,
            String msg,
            Boolean isalarm) {
        alarmcolumn += "sbz" + devicegroup + "dz" + addr + "jcd" + pointaddr + "qt";
        if (isalarm) {
            Appalarm appalarm = new Appalarm();
            alarmcolumn = isnull(alarmcolumn);
            boolean status = alarmcolumn.contains("微水");
            appalarm.setDeviceid(ad.getId());
            appalarm.setStationid(ad.getStationid());
            appalarm.setDevicegroup(ad.getDevicegroup());
            appalarm.setDeviceaddr(addr);
            appalarm.setPointaddr(pointaddr);
            appalarm.setPointname(pointname);
            if ((ad.getSimple().equals("gispd")) && status)
            appalarm.setDevicename("微水西电");
            else
            appalarm.setDevicename(ad.getName());
            appalarm.setAlarmcolumn(alarmcolumn);
            appalarm.setAlarmmessage(msg);
            appalarm.setAlarmlevel(2);
            Example example = new Example(Appalarm.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("stationid", appalarm.getStationid());
            criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
            criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
            criteria.andEqualTo("deviceid", appalarm.getDeviceid());
            criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
            criteria.andEqualTo("status", 1);
            if (Appalarmserviceimpl.selectCountByExample(example) == 0) {
                appalarm.setStarttime(new Date());
                appalarm.setStatus(1);
                Appalarmserviceimpl.insertSelective(appalarm);
            }
        } else {
            Appalarm appalarm = new Appalarm();
            alarmcolumn = isnull(alarmcolumn);
            boolean status = alarmcolumn.contains("微水");
            appalarm.setDeviceid(ad.getId());
            appalarm.setStationid(ad.getStationid());
            appalarm.setDevicegroup(ad.getDevicegroup());
            appalarm.setDeviceaddr(addr);
            appalarm.setPointaddr(pointaddr);
            appalarm.setPointname(pointname);
            if ((ad.getSimple().equals("gispd")) && status)
            appalarm.setDevicename("微水西电");
            else
            appalarm.setDevicename(ad.getName());

            appalarm.setAlarmcolumn(alarmcolumn);
            appalarm.setAlarmmessage(msg);
            Example example = new Example(Appalarm.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("stationid", appalarm.getStationid());
            criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
            criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
            criteria.andEqualTo("deviceid", appalarm.getDeviceid());
            criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
            criteria.andEqualTo("status", 1);
            appalarm.setStarttime(new Date());
            appalarm.setStatus(1);

            try {
                appalarm = Appalarmserviceimpl.selectOneByExample(example);
            } catch (MyBatisSystemException e) {
                Appalarmserviceimpl.deleteByExample(example);
                return;
            }
            if (appalarm == null) {
                return;
            }
            appalarm.setEndtime(new Date());
            appalarm.setStatus(0);
            appalarm.setAlarmlevel(null);
            appalarm.setData(null);
            appalarm.setAlarmmessage(null);
            Appalarmserviceimpl.updateByPrimaryKeySelective(appalarm);
        }
    }

    /**
     * 常规报警，传入ad
     * 
     * @param alarmcolumn 唯一项，报警列，请勿重复
     * @param addr        地址
     * @param pointaddr   监测点地址
     * @param pointname   监测点名称
     * @param msg         需要展示的报警详情
     * @param isalarm     是否需要恢复，true表示需要报警，false表示需要恢复为正常
     */
    public void GetNormalAlarm(String alarmcolumn, int devicegroup, int addr, int pointaddr, String pointname,
            String msg,
            Boolean isalarm, Appdevice ad) {
        alarmcolumn += "sbz" + devicegroup + "dz" + addr + "jcd" + pointaddr + "qt";
        if (isalarm) {
            Appalarm appalarm = new Appalarm();
            appalarm.setDeviceid(ad.getId());
            appalarm.setStationid(ad.getStationid());
            appalarm.setDevicegroup(ad.getDevicegroup());
            appalarm.setDeviceaddr(addr);
            appalarm.setPointaddr(pointaddr);
            appalarm.setPointname(pointname);
            appalarm.setDevicename(ad.getName());
            appalarm.setAlarmcolumn(alarmcolumn);
            appalarm.setAlarmmessage(msg);
            appalarm.setAlarmlevel(2);
            Example example = new Example(Appalarm.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("stationid", appalarm.getStationid());
            criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
            criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
            criteria.andEqualTo("deviceid", appalarm.getDeviceid());
            criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
            criteria.andEqualTo("status", 1);
            if (Appalarmserviceimpl.selectCountByExample(example) == 0) {
                appalarm.setStarttime(new Date());
                appalarm.setStatus(1);
                Appalarmserviceimpl.insertSelective(appalarm);
            }
        } else {
            Appalarm appalarm = new Appalarm();
            appalarm.setDeviceid(ad.getId());
            appalarm.setStationid(ad.getStationid());
            appalarm.setDevicegroup(ad.getDevicegroup());
            appalarm.setDeviceaddr(addr);
            appalarm.setPointaddr(pointaddr);
            appalarm.setPointname(pointname);
            appalarm.setDevicename(ad.getName());
            appalarm.setAlarmcolumn(alarmcolumn);
            appalarm.setAlarmmessage(msg);
            Example example = new Example(Appalarm.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("stationid", appalarm.getStationid());
            criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
            criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
            criteria.andEqualTo("deviceid", appalarm.getDeviceid());
            criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
            criteria.andEqualTo("status", 1);
            appalarm.setStarttime(new Date());
            appalarm.setStatus(1);

            try {
                appalarm = Appalarmserviceimpl.selectOneByExample(example);
            } catch (MyBatisSystemException e) {
                Appalarmserviceimpl.deleteByExample(example);
                return;
            }
            if (appalarm == null) {
                return;
            }
            appalarm.setEndtime(new Date());
            appalarm.setStatus(0);
            appalarm.setAlarmlevel(null);
            appalarm.setData(null);
            appalarm.setAlarmmessage(null);
            Appalarmserviceimpl.updateByPrimaryKeySelective(appalarm);
        }
    }

    public void GetNormalWarn(String alarmcolumn, int addr, int pointaddr, String pointname, String msg,
            Boolean isalarm) {
        if (isalarm) {
            Appalarm appalarm = new Appalarm();
            appalarm.setDeviceid(ad.getId());
            appalarm.setStationid(ad.getStationid());
            appalarm.setDevicegroup(ad.getDevicegroup());
            appalarm.setDeviceaddr(addr);
            appalarm.setPointaddr(pointaddr);
            appalarm.setPointname(pointname);
            appalarm.setDevicename(ad.getName());
            appalarm.setAlarmcolumn(alarmcolumn);
            appalarm.setAlarmmessage(msg);
            appalarm.setAlarmlevel(1);
            Example example = new Example(Appalarm.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("stationid", appalarm.getStationid());
            criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
            criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
            criteria.andEqualTo("deviceid", appalarm.getDeviceid());
            criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
            criteria.andEqualTo("status", 1);
            if (Appalarmserviceimpl.selectCountByExample(example) == 0) {
                appalarm.setStarttime(new Date());
                appalarm.setStatus(1);
                Appalarmserviceimpl.insertSelective(appalarm);
            }
        } else {
            Appalarm appalarm = new Appalarm();
            appalarm.setDeviceid(ad.getId());
            appalarm.setStationid(ad.getStationid());
            appalarm.setDevicegroup(ad.getDevicegroup());
            appalarm.setDeviceaddr(addr);
            appalarm.setPointaddr(pointaddr);
            appalarm.setPointname(pointname);
            appalarm.setDevicename(ad.getName());
            appalarm.setAlarmcolumn(alarmcolumn);
            appalarm.setAlarmmessage(msg);
            Example example = new Example(Appalarm.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("stationid", appalarm.getStationid());
            criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
            criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
            criteria.andEqualTo("deviceid", appalarm.getDeviceid());
            criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
            criteria.andEqualTo("status", 1);
            appalarm.setStarttime(new Date());
            appalarm.setStatus(1);

            try {
                appalarm = Appalarmserviceimpl.selectOneByExample(example);
            } catch (MyBatisSystemException e) {
                Appalarmserviceimpl.deleteByExample(example);
                return;
            }
            if (appalarm == null) {
                return;
            }
            appalarm.setEndtime(new Date());
            appalarm.setStatus(0);
            appalarm.setAlarmlevel(null);
            appalarm.setData(null);
            appalarm.setAlarmmessage(null);
            Appalarmserviceimpl.updateByPrimaryKeySelective(appalarm);
        }
    }

    public int GetAlarm(float value, float alarmValue, float alarmRelieveValue, float warnValue,
            float warnRelieveValue, int valueLevel, Boolean contrastStatus, String alarmcolumn, String alarmmessage,
            int addr,
            String pointname, int pointaddr) {
        int alarmLevel = 0;
        if (contrastStatus) {
            if (value >= alarmValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 2;
                        break;
                    case 1:
                        alarmLevel = 2;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value >= alarmRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value >= warnValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else if (value >= warnRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 0;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else {
                alarmLevel = 0;
            }
        } else {
            if (value <= alarmValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 2;
                        break;
                    case 1:
                        alarmLevel = 2;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value <= alarmRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 2;
                        break;
                }
            } else if (value <= warnValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 1;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else if (value <= warnRelieveValue) {
                switch (valueLevel) {
                    case 0:
                        alarmLevel = 0;
                        break;
                    case 1:
                        alarmLevel = 1;
                        break;
                    case 2:
                        alarmLevel = 1;
                        break;
                }
            } else {
                alarmLevel = 0;
            }
        }
        if (ad.getSimple().equals("o2andsf6"))
            return alarmLevel;
        Appalarm appalarm = new Appalarm();
        alarmcolumn = isnull(alarmcolumn);
        boolean status = alarmcolumn.contains("相放电量");
        // if((ad.getId()==8)&&status)
        // appalarm.setDeviceid(7);
        // else
        appalarm.setDeviceid(ad.getId());
        appalarm.setStationid(ad.getStationid());
        appalarm.setDevicegroup(ad.getDevicegroup());
        appalarm.setDeviceaddr(addr);
        if (pointaddr != -1) {
            appalarm.setPointaddr(pointaddr);
        }
        appalarm.setPointname(pointname);
        if ((ad.getSimple().equals("dlhl")) && status)
            appalarm.setDevicename("电缆局放");
        else
            appalarm.setDevicename(ad.getName());
        appalarm.setData(value);
        appalarm.setAlarmlevel(alarmLevel);
        appalarm.setWarnrelievevalue(warnRelieveValue);
        appalarm.setWarnvalue(warnValue);
        appalarm.setAlarmcolumn(alarmcolumn);
        appalarm.setAlarmrelievevalue(alarmRelieveValue);
        appalarm.setAlarmvalue(alarmValue);
        appalarm.setAlarmmessage(GetAlarmMessage(alarmLevel, alarmmessage));
        Example example = new Example(Appalarm.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("stationid", appalarm.getStationid());
        criteria.andEqualTo("devicegroup", appalarm.getDevicegroup());
        criteria.andEqualTo("deviceaddr", appalarm.getDeviceaddr());
        if (pointaddr != -1) {
            criteria.andEqualTo("pointaddr", appalarm.getPointaddr());
        }
        criteria.andEqualTo("deviceid", appalarm.getDeviceid());
        criteria.andEqualTo("alarmcolumn", appalarm.getAlarmcolumn());
        criteria.andEqualTo("status", 1);
        if (Appalarmserviceimpl.selectCountByExample(example) == 0) {// 如果不存在该告警记录，进入告警状态
            if (alarmLevel != 0) {
                appalarm.setStarttime(new Date());
                appalarm.setStatus(1);
                Appalarmserviceimpl.insertSelective(appalarm);
            }
        } else if ((valueLevel != 0 && alarmLevel == 0) || (valueLevel == 0 && alarmLevel == 0)) {// 设备进入正常状态，恢复告警,修改告警记录
            try {
                appalarm = Appalarmserviceimpl.selectOneByExample(example);
            } catch (MyBatisSystemException e) {
                Appalarmserviceimpl.deleteByExample(example);
                return 0;
            }
            if (appalarm == null) {
                return 0;
            }
            appalarm.setWarnrelievevalue(warnRelieveValue);
            appalarm.setWarnvalue(warnValue);
            appalarm.setAlarmvalue(alarmValue);
            appalarm.setAlarmrelievevalue(alarmRelieveValue);
            appalarm.setEndtime(new Date());
            appalarm.setStatus(0);
            appalarm.setAlarmlevel(null);
            appalarm.setData(null);
            appalarm.setAlarmmessage(null);
            Appalarmserviceimpl.updateByPrimaryKeySelective(appalarm);
        } else if (valueLevel != 0 && alarmLevel != 0) {
            try {
                appalarm = Appalarmserviceimpl.selectOneByExample(example);
            } catch (MyBatisSystemException e) {
                Appalarmserviceimpl.deleteByExample(example);
                return 0;
            }

            if (appalarm == null) {
                return 0;
            }
            if (valueLevel == 2 && alarmLevel == 1) {// 从告警进入预警状态，不进入
                appalarm.setAlarmlevel(null);
                appalarm.setData(null);
                appalarm.setAlarmmessage(null);
            } else {// 从预警进入告警
                appalarm.setWarnrelievevalue(warnRelieveValue);
                appalarm.setWarnvalue(warnValue);
                appalarm.setAlarmvalue(alarmValue);
                appalarm.setAlarmrelievevalue(alarmRelieveValue);
                appalarm.setAlarmlevel(alarmLevel);
                appalarm.setData(value);
                appalarm.setAlarmmessage(GetAlarmMessage(alarmLevel, alarmmessage));
            }
            appalarm.setStatus(1);
            Appalarmserviceimpl.updateByPrimaryKeySelective(appalarm);
        }
        return alarmLevel;
    }

    public String GetAlarmMessage(int alarmStatus, String alarmName) {
        String alarmMessage = "";
        // 获取报警消息
        // 参数:报警状态 0正常 1预警 2报警、报警名称(什么报警)、引用报警消息
        switch (alarmStatus) {
            case 0:
                alarmMessage = "";
                break;
            case 1:
                ;
                alarmMessage = alarmMessage + alarmName + languageManager.getLan().getWarning() + ",";
                break;
            case 2:
                alarmMessage = alarmMessage + alarmName + languageManager.getLan().getAlarm() + ",";
                break;
        }
        return alarmMessage;
    }

    public float float2(float value) {
        return Float.parseFloat(String.format("%.2f", value));
    }

    /**
     * 读取文件
     *
     * @param filePath 文件路径
     * @return 文件内容
     */
    public String readFile(String filePath) {
        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedReader br = Files.newBufferedReader(Paths.get(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                stringBuilder.append(line);
            }
            return stringBuilder.toString();
        } catch (IOException e) {
            setText("readFile" + e);
        }
        return null;
    }

    /**
     * 单行读取文件，并由处理函数
     * 
     * @param filePath 文件路径
     * @param consumer 带有字符串参数的处理函数
     */
    public void readFile(String filePath, Consumer<String> consumer) {
        try (BufferedReader br = Files.newBufferedReader(Paths.get(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                setText(line);
                consumer.accept(line);
            }
        } catch (IOException e) {
            setText("readFile" + e);
        }
    }

    /**
     * 读取文件的所有行，并用List返回
     *
     * @param filePath 文件路径
     * @return 文件内容
     */
    public List<String> readFileAllLines(String filePath) {
        try (BufferedReader br = Files.newBufferedReader(Paths.get(filePath))) {
            List<String> result = new ArrayList<>();
            String line;
            while ((line = br.readLine()) != null) {
                setText(line);
                result.add(line);
            }
            return result;
        } catch (IOException e) {
            setText("readFileAllLines" + e);
        }
        return null;
    }

    /**
     * 创建新文件写入
     *
     * @param filePath 文件路径
     * @param contents 要写入的内容
     * @return 是否写入成功
     */
    public boolean writeNewFile(String filePath, List<String> contents) {
        try (FileWriter writer = new FileWriter(filePath);
                BufferedWriter bw = new BufferedWriter(writer)) {
            for (String content : contents) {
                bw.write(content);
                bw.newLine();
            }
            return true;
        } catch (IOException e) {
            setText("writeNewFile" + e);
        }
        return false;
    }

    /**
     * 没有文件就创建文件写入，有就追加到文件的后面写入
     *
     * @param filePath 文件路径
     * @param contents 要写入的内容
     * @return 是否写入成功
     */
    public boolean writeAppendFile(String filePath, List<String> contents) {
        try (FileWriter writer = new FileWriter(filePath, true);
                BufferedWriter bw = new BufferedWriter(writer)) {
            for (String content : contents) {
                bw.append(content);
                bw.newLine();
            }
            return true;
        } catch (IOException e) {
            setText("writeAppendFile" + e);
        }
        return false;
    }

    /**
     * 没有文件就创建文件写入，有就追加到文件的后面写入
     *
     * @param filePath 文件路径
     * @param contents 要写入的内容
     * @return 是否写入成功
     */
    public boolean writeAppendFile(String filePath, String contents) {
        try (FileWriter writer = new FileWriter(filePath, true);
                BufferedWriter bw = new BufferedWriter(writer)) {
            bw.append(contents);
            return true;
        } catch (IOException e) {
            setText("writeAppendFile" + e);
        }
        return false;
    }

    /**
     * 没有文件就创建文件写入，有就追加到文件的后面写入
     *
     * @param filePath 文件路径
     * @param contents 要写入的内容
     * @return 是否写入成功
     */
    public boolean writeFile(String filePath, String contents) {
        try (FileWriter writer = new FileWriter(filePath, true);
                BufferedWriter bw = new BufferedWriter(writer)) {
            bw.write(contents);
            return true;
        } catch (IOException e) {
            setText("writeFile" + e);
        }
        return false;
    }

    /**
     * 删除文件
     * 
     * @param path 文件路径
     * @return 删除是否成功的标志
     */
    public boolean delFile(String path) {
        boolean flag = false;
        File file = new File(path.replace("/", "//")); // 根据文件路径创建File对象
        if (!file.exists()) { // 如果文件不存在
            return flag; // 返回删除失败标志
        }
        try {
            flag = file.delete(); // 删除文件
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag; // 返回删除结果的标志
    }

    /**
     * 添加文件
     * 
     * @param path 文件路径
     * @return 添加是否成功的标志
     * @throws IOException 如果创建文件时发生IO异常
     */
    public boolean addFile(String path) throws IOException {
        boolean flag = false;
        File file = new File(path); // 根据文件路径创建File对象
        if (!file.exists()) { // 如果文件不存在
            file.createNewFile(); // 创建新文件
        }
        return flag; // 返回添加结果的标志
    }

    /**
     * Integer判空置0
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static Integer isnull(Integer value) {
        if (value == null)
            return 0;
        else
            return value;
    }

    /**
     * Date判空置0000-00-00
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static Date isnull(Date value) {
        if (value == null)
            return new Date(0);
        else
            return value;
    }

    /**
     * String判空置空字符串
     * 用于异常判断
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static String isnull(String value) {
        if (value == null)
            return "";
        else
            return value;
    }

    /**
     * Integer判空置1
     * 用于异常判断
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static Integer nto(Integer value) {
        if (value == null)
            return 1;
        else
            return value;
    }

    /**
     * Float判空置1
     * 用于异常判断
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static Float nto(Float value) {
        if (value == null)
            return 1f;
        else
            return value;
    }

    /**
     * Long判空置0
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static Long isnull(Long value) {
        if (value == null)
            return 0L;
        else
            return value;
    }

    /**
     * Float判空置0
     * 
     * @param value
     * @return
     * @throws ParseException
     */
    public static Float isnull(Float value) {
        if (value == null)
            return 0f;
        else
            return value;
    }

    /**
     * 十六进制转正负数
     * 
     * (1,2个字节的)
     */
    public static int parseHex4(String num) {
        int ret = Integer.parseInt(num, 16);
        if (num.length() == 2) {
            return ret;
        } else if (num.length() == 4) {
            ret = ((ret & 0x8000) > 0) ? (ret - 0x10000) : (ret);
            return ret;
        } else {
            throw new NumberFormatException("Wrong length: " + num.length() + ", must be 4.");
        }
    }

    /**
     * 十六进制转正数
     * 
     * (1,2个字节的)
     */
    public static int parsePHex4(String num) {
        int ret = Integer.parseInt(num, 16);
        if (num.length() == 2 || num.length() == 4) {
            return ret;
        } else {
            throw new NumberFormatException("Wrong length: " + num.length() + ", must be 4.");
        }
    }

    /**
     * 十六进制转整数
     * (4个字节的)
     */
    public static Integer parseHex8(String num) {
        byte[] a = hexString2Bytes(num);
        if (a.length != 4) {
            try {
                throw new Exception(num + "长度不正确");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        int v0 = (a[0] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
        int v1 = (a[1] & 0xff) << 16;
        int v2 = (a[2] & 0xff) << 8;
        int v3 = (a[3] & 0xff);
        return v0 + v1 + v2 + v3;
    }

    /**
     * 累加和校验
     * 
     * @param data
     * @return
     */
    public String checksum(String data) {
        if (data == null || data.equals("")) {
            return "";
        }
        int total = 0;
        int len = data.length();
        int num = 0;
        while (num < len) {
            String s = data.substring(num, num + 2);

            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        /**
         * 用256求余最大是255，即16进制的FF
         */
        int mod = total % 256;
        String hex = Integer.toHexString(mod);
        len = hex.length();
        // 如果不够校验位的长度，补0,这里用的是两位校验
        if (len < 2) {
            hex = "0" + hex;
        }
        return hex.toUpperCase();
    }

    // 多态交给子类处理(comRunner中调用)
    public void startSendThread(Appdevice Appdevice) throws Exception {
    }

    @Async("threadPool")
    public void startReceiveThread() {
        isrecv.put(Thread.currentThread().getId(), true);
        while (isrecv.get(Thread.currentThread().getId()) != null) {
            recvCrc16Net();
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Async("threadPool")
    public void startReceiveComThread(String str) {
        // isrecv.put(Thread.currentThread().getId(), true);
        // while (isrecv.get(Thread.currentThread().getId()) != null) {
        // recv(str);
        // try {
        // Thread.sleep(interval);
        // } catch (InterruptedException e) {
        // e.printStackTrace();
        // }
        // }
    }

    @Async("threadPool")
    public void startReceive61850ClientThread() {
        isrecv.put(Thread.currentThread().getId(), true);
        while (isrecv.get(Thread.currentThread().getId()) != null) {
            receiveDatas("");
            try {
                Thread.sleep(timersp);
            } catch (InterruptedException e) {
                e.printStackTrace();
                setError("");
            }
        }
    }

    // 多态交给子类处理(comRunner中调用)
    /*
     * @param owner 类的实例
     * 
     * @param methodName 方法名
     * 
     * @param argsClass 参数类型
     * 
     * @param args 参数
     * 
     * @return
     * 
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static Object invokeMethod(Object owner, String methodName, Class[] argsClass, Object[] args)
            throws Exception {
        Object objRtn = null;
        Class ownerClass = owner.getClass();
        Method method = ownerClass.getMethod(methodName, argsClass);
        objRtn = method.invoke(owner, args);
        return objRtn;
    }

    // 累加和取反加1
    public byte ComputeCRC(byte[] pBuf) {
        int chm = 0;
        for (int i = 0; i < pBuf.length; i++) {
            chm ^= pBuf[i];
            for (int j = 0; j < 8; j++) {
                if ((chm & 0x01) != 0) {
                    chm = (chm >> 1) ^ 0x8C;
                } else {
                    chm >>= 1;
                }
            }
        }
        return (byte) chm;
    }

    // 4字节的CRC校验
    public boolean CheckCRC4(String pStr) {
        byte[] pBuf = HexUtil.hexString2Bytes(pStr);
        if (pBuf.length != 5) {
            return false;
        }
        int chm = 0;
        for (int i = 0; i < 4; i++) {
            chm ^= pBuf[i];
            for (int j = 0; j < 8; j++) {
                if ((chm & 0x01) != 0) {
                    chm = (chm >> 1) ^ 0x8C;
                } else {
                    chm >>= 1;
                }
            }
        }
        return chm == pBuf[4];
    }

    // 无论多少字节的CRC校验
    public boolean CheckCRC(String pStr) {
        byte[] pBuf = HexUtil.hexString2Bytes(pStr);
        int chm = 0;
        for (int i = 0; i < pBuf.length - 1; i++) {
            chm ^= pBuf[i];
            for (int j = 0; j < 8; j++) {
                if ((chm & 0x01) != 0) {
                    chm = (chm >> 1) ^ 0x8C;
                } else {
                    chm >>= 1;
                }
            }
        }
        return chm == pBuf[pBuf.length - 1];
    }

    /**
     * 列表深拷贝
     * 
     * @param <T>
     * @param src
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static List<Double> deepCopy(String[] src) {
        List<Double> dp = new ArrayList<>();
        for (int i = 0; i < src.length; i++) {
            dp.add(Double.parseDouble(src[i]));// 不变的源数据
        }
        return dp;
    }

    public static List<Double> deepCopy(List<Double> src) {
        List<Double> dp = new ArrayList<>();
        for (int i = 0; i < src.size(); i++) {
            dp.add(src.get(i));// 不变的源数据
        }
        return dp;
    }

    // 正则表达式从字符串中获取数字
    public static Integer strGetNum(String str) {
        Integer dest = -1;
        if (str.contains("COM")) {
            if (str != null) {
                dest = Integer.valueOf(str.replaceAll("[^0-9]", "")) - 1;
            }
        } else {
            if (str != null) {
                dest = Integer.valueOf(str.replaceAll("[^0-9]", ""));
            }
        }
        return dest;
    }

    // 正则表达式从字符串中获取数字
    public static String numGetStr(Integer num) {
        if (isWindows()) {
            num += 1;
            return "COM" + num;
        } else {
            return "ttyS" + num;
        }
    }

    public static boolean isNumeric(String str) {

        Pattern pattern = Pattern.compile("[0-9]*\\.?[0-9]+");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * @param poss      贝塞尔曲线控制点坐标
     * @param precision 精度，需要计算的该条贝塞尔曲线上的点的数目
     * @return 该条贝塞尔曲线上的点（二维坐标）
     */
    public float[][] bezier(float[][] poss, int precision) {
        // 维度，坐标轴数（二维坐标，三维坐标...）
        int dimersion = poss[0].length;
        // 贝塞尔曲线控制点数（阶数）
        int number = poss.length;
        // 控制点数不小于 2 ，至少为二维坐标系
        if (number < 2 || dimersion < 2)
            return null;
        float[][] result = new float[precision][dimersion];
        // 计算杨辉三角
        int[] mi = new int[number];
        mi[0] = mi[1] = 1;
        for (int i = 3; i <= number; i++) {
            int[] t = new int[i - 1];
            for (int j = 0; j < t.length; j++) {
                t[j] = mi[j];
            }
            mi[0] = mi[i - 1] = 1;
            for (int j = 0; j < i - 2; j++) {
                mi[j + 1] = t[j] + t[j + 1];
            }
        }
        // 计算坐标点
        for (int i = 0; i < precision; i++) {
            float t = (float) i / precision;
            for (int j = 0; j < dimersion; j++) {
                float temp = 0.0f;
                for (int k = 0; k < number; k++) {
                    temp += Math.pow(1 - t, number - k - 1) * poss[k][j] * Math.pow(t, k) * mi[k];
                }
                result[i][j] = temp;
            }
        }
        return result;
    }

    /**
     * @param poss      贝塞尔曲线控制点坐标
     * @param precision 精度，需要计算的该条贝塞尔曲线上的点的数目
     * @return 该条贝塞尔曲线上的点（二维坐标）
     */
    public int[][] bezier(int[][] poss, int precision) {
        // 维度，坐标轴数（二维坐标，三维坐标...）
        int dimersion = poss[0].length;
        // 贝塞尔曲线控制点数（阶数）
        int number = poss.length;
        // 控制点数不小于 2 ，至少为二维坐标系
        if (number < 2 || dimersion < 2)
            return null;
        int[][] result = new int[precision][dimersion];
        // 计算杨辉三角
        int[] mi = new int[number];
        mi[0] = mi[1] = 1;
        for (int i = 3; i <= number; i++) {
            int[] t = new int[i - 1];
            for (int j = 0; j < t.length; j++) {
                t[j] = mi[j];
            }
            mi[0] = mi[i - 1] = 1;
            for (int j = 0; j < i - 2; j++) {
                mi[j + 1] = t[j] + t[j + 1];
            }
        }
        // 计算坐标点
        for (int i = 0; i < precision; i++) {
            float t = (float) i / precision;
            for (int j = 0; j < dimersion; j++) {
                float temp = 0.0f;
                for (int k = 0; k < number; k++) {
                    temp += Math.pow(1 - t, number - k - 1) * poss[k][j] * Math.pow(t, k) * mi[k];
                }
                result[i][j] = (int) temp;
            }
        }
        return result;
    }

    public void delay(Integer t) {
        // 设置超时时间10s
        Long timestamp = System.currentTimeMillis() + 1000 * t;
        while (System.currentTimeMillis() < timestamp) {
            for (int n = 0; n < 4; ++n) {

            }
        }
    }

    /*
     * 接收之前做的事情
     * 
     * @param str
     */
    public void receiveData(String str) {

        rlock.lock();
        System.out.println(str);
        try {
            receiveDatas(str);
            Thread.sleep(timersp);
            if (sendFlag) {
                sendCondition.signal();
            }
        } catch (Exception ex) {
            setError(ex.toString());
            ex.printStackTrace();
        } finally {
            sendFlag = true;
            rlock.unlock();
        }
    }

    public void receiveDatas(String str) {
        System.out.println(str + "111");
    }

    /**
     * 遥控命令,只需要构造发送报文带入参数
     * 
     * @param cstr
     */
    public void ControlCommand(String cstr) {
        cstr = cstr + CRC16.calcCrc16(cstr);
        controllerCmd = cstr;
        rlock.lock();
        try {
            Thread.sleep(1000);
            Send(controllerCmd);
            controllerCmd = "";
            recvCondition.signal();
            controlCondition.await(3000, TimeUnit.MILLISECONDS);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            rlock.unlock();
        }
    }

    public String zeroFormat(String str, int len) {
        byte[] bdeviceName = new byte[1024];
        bdeviceName = str.getBytes();
        int l = bdeviceName.length;

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < len - l; i++) {
            sb.append("\0");
        }
        sb.append(str);
        return sb.toString();
    }

    public String zerorFormat(String str, int len) {
        byte[] bdeviceName = new byte[1024];
        bdeviceName = str.getBytes();
        int l = bdeviceName.length;

        StringBuffer sb = new StringBuffer();
        sb.append(str);
        for (int i = 0; i < len - l; i++) {
            sb.append("\0");
        }
        return sb.toString();
    }

    public void IEC104() {
        Iec104Config iec104Config = new Iec104Config();
        iec104Config.setFrameAmountMax((short) 2);
        iec104Config.setTerminnalAddress((short) 1);
        try {
            Iec104MasterFactory.createTcpClientMaster("127.0.0.1",
                    2404).setDataHandler(new MasterSysDataHandler())
                    .setConfig(iec104Config).run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean reloadAppdevice() {
        Appdevice device = appdeviceserviceimpl.selectByPrimaryKey(ad);
        if (device != null) {
            this.ad = device;
            return true;
        } else {
            return false;
        }
    }
}